/**
 * @file    drv_flash2eep.c
 * @author  yhy
 * @brief   flash模拟eeprom
 * @version 1.00
 * @date    2025-08-14
 *
 * @copyright Copyright (c) 2025
 *
 * @details
 * Change Logs:
 * Date           Author       Notes
 * 2025-08-14     yhy          the first version V1.00
 *
 */
#include "drv_flash2eep.h"

#include <stdlib.h>
#include <string.h>

static uint16_t        snf_flash2eep_calc_crc16(const uint8_t *data, uint8_t length);
static uint32_t        snf_flash2eep_align_address(uint32_t addr);
static uint32_t        snf_flash2eep_calc_item_size(uint8_t data_len);
static result_e        snf_flash2eep_sector_migrate(void);
static result_e        snf_flash2eep_scan_and_rebuild(void);
static result_e        snf_flash2eep_write_item(uint8_t index, const uint8_t *data, uint8_t length);
static bool            snf_flash2eep_verify_item(uint32_t addr, eeprom_item_header_t *header);
static eeprom_status_t eeprom_status              = { 0 };
static const snf_flash_partition_t *data_part4eep = NULL;

/* CRC16查找表（多项式：0x1021，初始值：0xFFFF） */
static const uint16_t crc16_table[256] = {
    0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C,
    0xD1AD, 0xE1CE, 0xF1EF, 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, 0x9339, 0x8318,
    0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4,
    0x5485, 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, 0x3653, 0x2672, 0x1611, 0x0630,
    0x76D7, 0x66F6, 0x5695, 0x46B4, 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, 0x48C4,
    0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969,
    0xA90A, 0xB92B, 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, 0xDBFD, 0xCBDC, 0xFBBF,
    0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
    0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13,
    0x2E32, 0x1E51, 0x0E70, 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, 0x9188, 0x81A9,
    0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046,
    0x6067, 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, 0x02B1, 0x1290, 0x22F3, 0x32D2,
    0x4235, 0x5214, 0x6277, 0x7256, 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, 0x34E2,
    0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E,
    0xC71D, 0xD73C, 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, 0xD94C, 0xC96D, 0xF90E,
    0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
    0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1,
    0x1AD0, 0x2AB3, 0x3A92, 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, 0x7C26, 0x6C07,
    0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9,
    0x9FF8, 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
};

/**
 * @brief 初始化EEPROM系统
 *
 * @return result_e 错误码
 */
result_e snf_flash2eep_init(void)
{
    /* 查找数据分区 */
    data_part4eep = snf_drv_flash_partition_find(FLASH_PART_NAME_DATA);
    if (!data_part4eep) {
        return RESULT_STATUS_EEPROM_ERR_INIT_FAIL;
    }

    /* 验证分区大小 */
    if (data_part4eep->len < EEPROM_TOTAL_SIZE) {
        return RESULT_STATUS_EEPROM_ERR_INIT_FAIL;
    }

    /* 初始化EEPROM状态结构 */
    memset(&eeprom_status, 0, sizeof(eeprom_status));

    /* 扫描并重建索引映射表 */
    result_e result = snf_flash2eep_scan_and_rebuild();
    if (result != RESULT_STATUS_EEPROM_ERR_OK) {
        return result;
    }

    eeprom_status.initialized = true;
    return RESULT_STATUS_OK;
}

/**
 * @brief 强制触发扇区迁移
 *
 * @return result_e 错误码
 */
result_e snf_flash2eep_force_migrate(void)
{
    if (!eeprom_status.initialized) {
        return RESULT_STATUS_EEPROM_ERR_INIT_FAIL;
    }

    /* 直接调用内部扇区迁移函数 */
    return snf_flash2eep_sector_migrate();
}

/**
 * @brief 注册逻辑索引
 *
 * @param   index               逻辑索引
 * @return  result_e      错误码
 */
result_e snf_flash2eep_register(uint8_t index)
{
    if (!eeprom_status.initialized) {
        return RESULT_STATUS_EEPROM_ERR_INIT_FAIL;
    }

    if (index > EEPROM_MAX_INDEX) {
        return RESULT_STATUS_EEPROM_ERR_INVALID_INDEX;
    }

    /* 索引注册成功(实际上只是验证索引有效性) */
    return RESULT_STATUS_EEPROM_ERR_OK;
}

/**
 * @brief 写入数据到指定索引
 *
 * @param   index               逻辑索引
 * @param   data                数据指针
 * @param   length              数据长度
 * @return  result_e      错误代码
 */
result_e snf_flash2eep_write(uint8_t index, const uint8_t *data, uint8_t length)
{
    if (!eeprom_status.initialized) {
        return RESULT_STATUS_EEPROM_ERR_INIT_FAIL;
    }

    if (index > EEPROM_MAX_INDEX) {
        return RESULT_STATUS_EEPROM_ERR_INVALID_INDEX;
    }

    if (!data || length == 0 || length > EEPROM_MAX_DATA_LEN) {
        return RESULT_STATUS_EEPROM_ERR_DATA_TOO_LONG;
    }

    return snf_flash2eep_write_item(index, data, length);
}

int snf_flash2eep_read(uint8_t index, uint8_t *buf, uint8_t buf_size)
{
    if (!eeprom_status.initialized) {
        return -RESULT_STATUS_EEPROM_ERR_INIT_FAIL;
    }

    if (index > EEPROM_MAX_INDEX || !buf) {
        return -RESULT_STATUS_EEPROM_ERR_INVALID_INDEX;
    }

    eeprom_index_map_t *map_entry = &eeprom_status.index_map[index];
    if (!map_entry->valid) {
        return 0; /* 无数据 */
    }

    if (buf_size < map_entry->length) {
        return -RESULT_STATUS_EEPROM_ERR_DATA_TOO_LONG;
    }

    /* 验证数据项有效性 */
    eeprom_item_header_t header;
    if (!snf_flash2eep_verify_item(map_entry->addr, &header)) {
        /* 数据损坏, 标记为无效 */
        map_entry->valid = false;
        --eeprom_status.valid_items;
        return -RESULT_STATUS_EEPROM_ERR_CRC_FAIL;
    }

    /* 读取数据 */
    result_e result = snf_drv_flash_partition_read(
        data_part4eep, map_entry->addr + sizeof(eeprom_item_header_t), buf, map_entry->length);
    if (result != RESULT_STATUS_FLASH_ERR_OK) {
        return -RESULT_STATUS_EEPROM_ERR_FLASH_FAIL;
    }

    return map_entry->length;
}

/**
 * @brief 获取EEPROM状态信息
 *
 * @return eeprom_status_t* EEPROM状态指针
 */
eeprom_status_t *snf_flash2eep_get_status(void) { return &eeprom_status; }

/**
 * @brief 格式化EEPROM
 *
 * @return result_e 错误码
 */
result_e snf_flash2eep_format(void)
{
    if (!eeprom_status.initialized || !data_part4eep) {
        return RESULT_STATUS_EEPROM_ERR_INIT_FAIL;
    }

    /* 擦出整个数据分区 */
    result_e result = snf_drv_flash_partition_erase_all(data_part4eep);
    if (result != RESULT_STATUS_FLASH_ERR_OK) {
        return RESULT_STATUS_EEPROM_ERR_FLASH_FAIL;
    }

    /* 重新初始化 */
    return snf_flash2eep_init();
}

/**
 * @brief 计算CRC16校验值
 * @param   data            要校验的数据
 * @param   length          数据长度
 * @return  uint16_t        CRC16校验值
 */
static uint16_t snf_flash2eep_calc_crc16(const uint8_t *data, uint8_t length)
{
    uint16_t crc = 0xFFFF;

    for (uint8_t i = 0; i < length; i++) {
        uint8_t tbl_idx = ((crc >> 8) ^ data[i]) & 0xFF;
        crc             = ((crc << 8) ^ crc16_table[tbl_idx]) & 0xFFFF;
    }

    return crc;
}

/**
 * @brief 将地址或大小对齐到8字节边界
 *
 * @param   addr       原始地址或大小
 * @return  uint32_t   对齐后的地址或大小
 */
static uint32_t snf_flash2eep_align_address(uint32_t addr)
{
    return (addr + EEPROM_ALIGN_SIZE - 1) & ~(EEPROM_ALIGN_SIZE - 1);
}

/**
 * @brief 计算数据项总大小（包含头部和填充）
 *
 * @param   data_len 数据长度
 * @return  uint32_t 数据项总大小
 */
static uint32_t snf_flash2eep_calc_item_size(uint8_t data_len)
{
    uint32_t total_size = sizeof(eeprom_item_header_t) + data_len;
    return snf_flash2eep_align_address(total_size);
}

/**
 * @brief 验证数据项的有效性
 *
 * @param   addr    数据项地址
 * @param   header  读取的数据项头部信息
 * @return  true    有效
 * @return  false   无效
 */
static bool snf_flash2eep_verify_item(uint32_t addr, eeprom_item_header_t *header)
{
    if (!data_part4eep || !header) {
        return false;
    }

    /* 检查地址8字节对齐 */
    if (addr % EEPROM_ALIGN_SIZE != 0) {
        ++eeprom_status.alignment_errors;
        return false;
    }

    /* 读取头部信息 */
    result_e result =
        snf_drv_flash_partition_read(data_part4eep, addr, (uint8_t *)header, sizeof(eeprom_item_header_t));
    if (result != RESULT_STATUS_FLASH_ERR_OK) {
        return false;
    }

    /* 验证魔数 */
    if (header->magic != EEPROM_MAGIC_HEADER) {
        return false;
    }

    /* 验证索引范围 */
    if (header->index > EEPROM_MAX_INDEX) {
        return false;
    }

    /* 验证数据长度 */
    if (header->length == 0 || header->length > EEPROM_MAX_DATA_LEN) {
        return false;
    }

    /* 读取数据并验证CRC */
    uint8_t data_buf[EEPROM_MAX_DATA_LEN];
    result = snf_drv_flash_partition_read(data_part4eep, addr + sizeof(eeprom_item_header_t), data_buf,
                                          header->length);
    if (result != RESULT_STATUS_FLASH_ERR_OK) {
        return false;
    }

    uint16_t calc_crc = snf_flash2eep_calc_crc16(data_buf, header->length);
    if (calc_crc != header->crc) {
        return false;
    }

    return true;
}

/**
 * @brief 扫描Flash并重建索引映射表
 *
 * @return result_e 错误码
 */
static result_e snf_flash2eep_scan_and_rebuild(void)
{
    if (!data_part4eep) {
        return RESULT_STATUS_EEPROM_ERR_INIT_FAIL;
    }

    /* 清空索引映射表 */
    memset(eeprom_status.index_map, 0, sizeof(eeprom_status.index_map));
    eeprom_status.valid_items   = 0;
    eeprom_status.active_sector = 0;
    eeprom_status.write_ptr     = 0;

    uint32_t sector0_items = 0, sector1_items = 0;
    uint32_t sector0_write_ptr = 0, sector1_write_ptr = 0;

    /* 扫描两个扇区 */
    for (uint8_t sector = 0; sector < EEPROM_SECTOR_COUNT; ++sector) {
        uint32_t sector_base  = sector * EEPROM_SECTOR_SIZE;
        uint32_t current_addr = sector_base;
        uint32_t sector_items = 0;

        while (current_addr < sector_base + EEPROM_SECTOR_SIZE) {
            /* 确保地址8字节对齐 */
            current_addr = snf_flash2eep_align_address(current_addr);

            eeprom_item_header_t header;
            if (!snf_flash2eep_verify_item(current_addr, &header)) {
                /* 遇到无效数据, 认为是扇区结束 */
                break;
            }

            ++sector_items;

            /* 更新索引映射表（保留最新版本） */
            eeprom_index_map_t *map_entry = &eeprom_status.index_map[header.index];
            if (!map_entry->valid || header.version > map_entry->version) {
                map_entry->addr    = current_addr;
                map_entry->version = header.version;
                map_entry->length  = header.length;
                map_entry->valid   = true;
            }

            /* 移动到下一个数据项 */
            current_addr += snf_flash2eep_calc_item_size(header.length);
        }

        if (sector == 0) {
            sector0_items     = sector_items;
            sector0_write_ptr = current_addr;
        }
        else {
            sector1_items     = sector_items;
            sector1_write_ptr = current_addr;
        }
    }

    /* 智能扇区选择算法 - 基于数据新旧程度和负载均衡 */
    uint8_t selected_sector = 0;

    /* 计算每个扇区的最新版本号 */
    uint16_t sector0_max_version = 0, sector1_max_version = 0;
    bool     sector0_has_data = false, sector1_has_data = false;

    for (uint16_t i = 0; i <= EEPROM_MAX_INDEX; ++i) {
        eeprom_index_map_t *map_entry = &eeprom_status.index_map[i];
        if (map_entry->valid) {
            /* 确定数据项属于哪个扇区 */
            uint8_t item_sector = (map_entry->addr < EEPROM_SECTOR_SIZE) ? 0 : 1;

            if (item_sector == 0) {
                sector0_has_data = true;
                if (map_entry->version > sector0_max_version) {
                    sector0_max_version = map_entry->version;
                }
            }
            else {
                sector1_has_data = true;
                if (map_entry->version > sector1_max_version) {
                    sector1_max_version = map_entry->version;
                }
            }
        }
    }

    /* 扇区选择策略：优先选择包含最新数据的扇区 */
    if (!sector0_has_data && !sector1_has_data) {
        /* 两个扇区都没有数据，选择使用次数较少的扇区 */
        selected_sector = (eeprom_status.sector_use_count[0] <= eeprom_status.sector_use_count[1]) ? 0 : 1;
    }
    else if (!sector0_has_data) {
        /* 只有扇区1有数据 */
        selected_sector = 1;
    }
    else if (!sector1_has_data) {
        /* 只有扇区0有数据 */
        selected_sector = 0;
    }
    else {
        /* 两个扇区都有数据，比较最新版本号 */
        if (sector0_max_version > sector1_max_version) {
            /* 扇区0包含更新的数据 */
            selected_sector = 0;
        }
        else if (sector1_max_version > sector0_max_version) {
            /* 扇区1包含更新的数据 */
            selected_sector = 1;
        }
        else {
            /* 版本号相等，优先考虑写入指针位置（表示最近写入活动） */
            uint32_t sector0_offset = sector0_write_ptr % EEPROM_SECTOR_SIZE;
            uint32_t sector1_offset = sector1_write_ptr % EEPROM_SECTOR_SIZE;

            if (abs((int)sector0_offset - (int)sector1_offset) > 64) {
                /* 写入指针位置差异较大，选择写入指针更靠后的扇区 */
                selected_sector = (sector0_offset > sector1_offset) ? 0 : 1;
            }
            else if (abs((int)sector0_items - (int)sector1_items) > 2) {
                /* 写入指针位置相近，但数据项数量差异较大，选择数据项较多的扇区 */
                selected_sector = (sector0_items >= sector1_items) ? 0 : 1;
            }
            else {
                /* 写入指针和数据项数量都相近，选择使用次数较少的扇区（负载均衡） */
                selected_sector =
                    (eeprom_status.sector_use_count[0] <= eeprom_status.sector_use_count[1]) ? 0 : 1;
            }
        }
    }

    eeprom_status.active_sector = selected_sector;
    eeprom_status.write_ptr     = (selected_sector == 0) ? sector0_write_ptr : sector1_write_ptr;

    /* 更新扇区使用计数 */
    eeprom_status.sector_use_count[selected_sector]++;

    /* 更新优选扇区（下次优先考虑使用次数较少的扇区） */
    eeprom_status.preferred_sector =
        (eeprom_status.sector_use_count[0] <= eeprom_status.sector_use_count[1]) ? 0 : 1;

    /* 统计有效数据项 */
    for (uint16_t i = 0; i <= EEPROM_MAX_INDEX; ++i) {
        if (eeprom_status.index_map[i].valid) {
            ++eeprom_status.valid_items;
        }
    }

    /* 计算剩余空间 */
    uint32_t sector_base     = eeprom_status.active_sector * EEPROM_SECTOR_SIZE;
    eeprom_status.free_space = (sector_base + EEPROM_SECTOR_SIZE) - eeprom_status.write_ptr;

    return RESULT_STATUS_EEPROM_ERR_OK;
}

/**
 * @brief 执行扇区迁移 - 智能扇区轮换策略
 *
 * @return result_e 错误码
 */
static result_e snf_flash2eep_sector_migrate(void)
{
    if (!data_part4eep) {
        return RESULT_STATUS_EEPROM_ERR_INIT_FAIL;
    }

    /* 智能目标扇区选择 - 优先选择使用次数较少的扇区 */
    uint8_t target_sector;
    if (eeprom_status.sector_use_count[0] < eeprom_status.sector_use_count[1]) {
        target_sector = 0;
    }
    else if (eeprom_status.sector_use_count[1] < eeprom_status.sector_use_count[0]) {
        target_sector = 1;
    }
    else {
        /* 使用次数相等时，选择非当前活动扇区 */
        target_sector = eeprom_status.active_sector == 0 ? 1 : 0;
    }

    uint32_t target_base = target_sector * EEPROM_SECTOR_SIZE;

    /* 擦出目标扇区 */
    result_e result = snf_drv_flash_partition_erase(data_part4eep, target_base, EEPROM_SECTOR_SIZE);
    if (result != RESULT_STATUS_FLASH_ERR_OK) {
        return RESULT_STATUS_EEPROM_ERR_FLASH_FAIL;
    }

    /* 复制有效数据到目标扇区 */
    uint32_t write_addr = target_base;

    for (uint16_t i = 0; i <= EEPROM_MAX_INDEX; ++i) {
        eeprom_index_map_t *map_entry = &eeprom_status.index_map[i];
        if (!map_entry->valid) {
            continue;
        }

        /* 读取原数据 */
        uint8_t  item_buf[sizeof(eeprom_item_header_t) + EEPROM_MAX_DATA_LEN];
        uint32_t item_size = snf_flash2eep_calc_item_size(map_entry->length);

        result = snf_drv_flash_partition_read(data_part4eep, map_entry->addr, item_buf, item_size);
        if (result != RESULT_STATUS_FLASH_ERR_OK) {
            /* 跳过读取失败的数据 */
            continue;
        }

        /* 写入到新位置 */
        write_addr = snf_flash2eep_align_address(write_addr);
        result     = snf_drv_flash_partition_write(data_part4eep, write_addr, item_buf, item_size);
        if (result != RESULT_STATUS_FLASH_ERR_OK) {
            return RESULT_STATUS_EEPROM_ERR_FLASH_FAIL;
        }

        /* 更新映射表 */
        map_entry->addr = write_addr;
        write_addr += item_size;
    }

    /* 切换活动扇区 */
    eeprom_status.active_sector = target_sector;
    eeprom_status.write_ptr     = write_addr;
    eeprom_status.free_space    = (target_base + EEPROM_SECTOR_SIZE) - write_addr;

    /* 更新扇区使用统计信息 */
    eeprom_status.sector_use_count[target_sector]++;
    eeprom_status.sector_migration_count++;

    /* 更新优选扇区（下次优先考虑使用次数较少的扇区） */
    eeprom_status.preferred_sector =
        (eeprom_status.sector_use_count[0] <= eeprom_status.sector_use_count[1]) ? 0 : 1;

    return RESULT_STATUS_EEPROM_ERR_OK;
}

/**
 * @brief 写入数据项到Flash, MAX 255字节
 *
 * @param index             逻辑索引
 * @param data              待写入到数据
 * @param length            据长度
 * @return result_e   错误代码
 */
static result_e snf_flash2eep_write_item(uint8_t index, const uint8_t *data, uint8_t length)
{
    if (!data_part4eep) {
        return RESULT_STATUS_EEPROM_ERR_INIT_FAIL;
    }

    uint32_t item_size = snf_flash2eep_calc_item_size(length);

    /* 检查空间是否足够 */
    if (eeprom_status.free_space < item_size) {
        /* 执行扇区迁移 */
        result_e migrate_result = snf_flash2eep_sector_migrate();
        if (migrate_result != RESULT_STATUS_EEPROM_ERR_OK) {
            return migrate_result;
        }

        /* 再次检查空间 */
        if (eeprom_status.free_space < item_size) {
            return RESULT_STATUS_EEPROM_ERR_NO_SPACE;
        }
    }

    /* 准备数据项 */
    uint8_t item_buf[sizeof(eeprom_item_header_t) + EEPROM_MAX_DATA_LEN];
    memset(item_buf, EEPROM_PADDING_BYTE, sizeof(item_buf));

    eeprom_item_header_t *header = (eeprom_item_header_t *)item_buf;
    header->magic                = EEPROM_MAGIC_HEADER;
    header->index                = index;
    header->length               = length;
    header->crc                  = snf_flash2eep_calc_crc16(data, length);
    header->version =
        eeprom_status.index_map[index].valid ? (eeprom_status.index_map[index].version + 1) : 1;

    /* 复制数据 */
    memcpy(item_buf + sizeof(eeprom_item_header_t), data, length);

    /* 确保写入地址8字节对齐 */
    eeprom_status.write_ptr = snf_flash2eep_align_address(eeprom_status.write_ptr);

    /* 写入Flash */
    result_e result =
        snf_drv_flash_partition_write(data_part4eep, eeprom_status.write_ptr, item_buf, item_size);
    if (result != RESULT_STATUS_FLASH_ERR_OK) {
        return RESULT_STATUS_EEPROM_ERR_FLASH_FAIL;
    }

    /* 更新索引映射表 */
    eeprom_index_map_t *map_entry = &eeprom_status.index_map[index];
    if (!map_entry->valid) {
        ++eeprom_status.valid_items;
    }

    map_entry->addr    = eeprom_status.write_ptr;
    map_entry->version = header->version;
    map_entry->length  = length;
    map_entry->valid   = true;

    /* 更新写入指针和剩余空间 */
    eeprom_status.write_ptr += item_size;
    eeprom_status.free_space -= item_size;

    return RESULT_STATUS_OK;
}
